如果守門人自己把鑰匙亂放,再高的城牆也沒用。
前面幾天,我們布好了四道防線:
這些都在檢查「我們的輸入與輸出」。但在 DevSecOps 的流程裡,還有一個常被忽略的對象:CI/CD Pipeline 本身。
想像一下,你把城牆巡邏、補給車安檢、臥底清查都做得滴水不漏,結果守門的士兵卻隨手把鑰匙丟在門口。這就是很多團隊的 pipeline 狀態。
今天,我們要談的不是檢查程式碼,而是確保 自動化流程(GitHub Actions)本身不成為漏洞來源。
Pipeline 本身有權限:CI/CD 跑的 workflow 會拿到存取 repo、部署伺服器、甚至雲端憑證的權限。
攻擊面更大:一旦 workflow 被惡意利用,就能直接跳過所有防線。
歷史慘痛案例:很多供應鏈攻擊不是程式碼出錯,而是「攻破 CI/CD 系統」後注入惡意程式碼。
GitHub 預設會給每個 workflow 一把「大鑰匙」── GITHUB_TOKEN,它能存取 repo 的讀寫。
但實際上,很多工作只需要讀,不需要寫。
permissions:
contents: read # 只允許讀程式碼
issues: none # 不允許建立/修改 issue
pull-requests: none
這樣就能避免 pipeline 被濫用來竄改 repo 內容。
有些惡意 PR 會刻意觸發大量 workflow,試圖造成資源消耗或干擾。
GitHub 提供 concurrency 機制:
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
這樣,同一個分支的 workflow 只會保留最新一次,避免「刷爆 CI」的狀況。
不要讓 workflow 在任何人 push 任意檔案時都觸發。可以限制在特定目錄或分支:
on:
push:
branches: [ master ]
paths:
- '**/*.py'
- '.github/workflows/**'
這樣就不會有人在 repo 裡隨便放一個檔案,就讓整個 CI pipeline 被跑爆。
在做網路工程師的時候,最常處理的就是 AD 權限控管。
那時候的原則是:
帳號只給需要的權限
系統日誌要能追溯誰做了什麼
現在到 DevSecOps,其實也是同一套邏輯:
Workflow 只給需要的權限(最小化原則)
pipeline 的觸發要有邏輯規則,避免被濫用
到今天我們已經把 DevSecOps 入門的基礎拼圖補齊:
四道外部防線 → 程式碼、依賴、Secrets、容器
隱形內部防線 → Pipeline 本身的安全
這樣一來我們不只檢查「帶進城牆的東西」,也檢查「守門的士兵有沒有亂搞」。
基礎安全循環算是完整建了起來。